package sm2ext

import (
	"crypto/elliptic"
	"encoding/asn1"
	"encoding/pem"
	"errors"
	"fmt"
	"github.com/tjfoc/gmsm/sm2"
	"io/ioutil"
	"reflect"
)

type pubkey_openssl struct {
	Algo struct {
		Algorithm  asn1.ObjectIdentifier
		AlgoParams asn1.RawValue //AlgorithmIdentifier
	}

	PublicKey asn1.BitString
}

func ParseSm2PublicKey_openssl(der []byte) (*sm2.PublicKey, error) {
	var pubkey pubkey_openssl

	if _, err := asn1.Unmarshal(der, &pubkey); err != nil {
		return nil, err
	}
	if !reflect.DeepEqual(pubkey.Algo.Algorithm, oidSM2) {
		return nil, errors.New("x509: not sm2 elliptic curve")
	}
	curve := sm2.P256Sm2()
	x, y := elliptic.Unmarshal(curve, pubkey.PublicKey.Bytes)
	pub := sm2.PublicKey{
		Curve: curve,
		X:     x,
		Y:     y,
	}
	return &pub, nil
}

func Read_public_pem_file_openssl(pemFileName string) (*sm2.PublicKey, error) {
	pemTmp, err := ioutil.ReadFile(pemFileName)
	if err != nil {
		fmt.Println("read file error:", err)
		return nil, err
	}
	var block *pem.Block
	block, _ = pem.Decode(pemTmp)
	if block == nil {
		return nil, errors.New("failed to decode public key")
	}

	pubKey, err := ParseSm2PublicKey_openssl(block.Bytes)

	return pubKey, err
}
